package org.MyToolsProject;

import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

public class OperateBiLiBiLiUtil {

    public static List<M4Snode> analysisEntryJson(String srcDir){
        List<M4Snode> m4SnodeList = new ArrayList<>();
        File dirFile = new File(srcDir);
        File[] zhuan_ji_list = dirFile.listFiles();
        if (zhuan_ji_list != null ) {
            // 遍历专辑列表
            for (File zhuan_ji : zhuan_ji_list){
                File[] vidioDataList = zhuan_ji.listFiles();
                if(vidioDataList != null){
                    // 遍历专辑里面的视频列表
                    for (File videoData : vidioDataList){
                        String videoDataPath = videoData.getAbsolutePath();
                        // 当前目录必定有 entry.json 文件
                        File entryJson = new File(videoDataPath + "\\entry.json");
                        JSONObject entryJsonObject = getTitleByEntryJson(entryJson);
                        if(entryJsonObject != null){
                            String typeTagPath = videoDataPath + "\\" + entryJsonObject.getString("type_tag");
                            // 检测路径是否存在
                            Path checkPath = Paths.get(typeTagPath);
                            if(!Files.exists(checkPath)){
                                throw new RuntimeException("视频文件目录无法找到：" + checkPath );
                            }

                            String audioPath = typeTagPath + "\\audio.m4s";//音频路径
                            checkPath = Paths.get(audioPath);
                            if(!Files.exists(checkPath)){
                                throw new RuntimeException("音频文件无法找到：" + checkPath );
                            }

                            String videoPath = typeTagPath + "\\video.m4s";//视频路径
                            checkPath = Paths.get(videoPath);
                            if(!Files.exists(checkPath)){
                                throw new RuntimeException("视频文件无法找到：" + checkPath );
                            }

                            M4Snode snode = new M4Snode();
                            snode.setAudioPath(audioPath);
                            snode.setVideoPath(videoPath);
                            snode.setOwnerName(entryJsonObject.getString("owner_name"));
                            snode.setCreateTime(entryJsonObject.getLong("time_create_stamp"));
                            snode.setUpdateTime(entryJsonObject.getLong("time_update_stamp"));
                            JSONObject pageDataObject = entryJsonObject.getJSONObject("page_data");
                            snode.setPageData(pageDataObject);
                            m4SnodeList.add(snode);
                        }
                    }
                }
            }
        }else {
            throw new RuntimeException("文件夹路径为空！：" + srcDir );
        }
        Collections.sort(m4SnodeList, new Comparator<M4Snode>() {
            @Override
            public int compare(M4Snode o1, M4Snode o2) {
                return (int)(o1.getUpdateTime()-o2.getUpdateTime());
            }
        });
        for (M4Snode data : m4SnodeList){
            System.out.println(data);
        }
        return m4SnodeList;
    }

    // 合并视频文件
    public static List<CommandLine> getMergeCommandLine(String outDir,List<M4Snode> m4SnodeList) {
        File dirFile = new File(outDir);
        if(dirFile.exists()){
           throw new RuntimeException("文件夹已存在！" + outDir);
        }
        List<CommandLine> commandLineList = new ArrayList<>(m4SnodeList.size());
        dirFile.mkdirs();
        outDir = dirFile.getAbsolutePath();
        try {
            System.out.println("开始生成合并命令！！！");
            for (int i = 0; i < m4SnodeList.size(); i++) {
                M4Snode snode = m4SnodeList.get(i);
                JSONObject pageDataObject = snode.getPageData();
                String title = pageDataObject.getString("download_subtitle");
                if(title.length() > 30){
                    title = title.substring(0,30);
                }
                title = title + "_" + snode.getOwnerName();
                title = removeUnChinese(title);
                String mp4Path = outDir + "\\" + (i+1) +"_"+title+".mp4";
                //ffmpeg -i video.m4s -i audio.m4s -codec copy output.mp4
                String command = "ffmpeg -i %s -i %s -codec copy %s";
                command = String.format(command
                        , getEscapeSymbol(snode.getVideoPath())
                        , getEscapeSymbol(snode.getAudioPath())
                        , getEscapeSymbol(mp4Path));
                System.out.println( String.format("执行第%s条命令：",(i+1)) + command);
                CommandLine commandLine = CommandLine.parse(command);
                commandLineList.add(commandLine);
            }
            System.out.println("开始生成合并命令完成！");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("发生错误！：" + e.getMessage() );
        }
        return commandLineList;
    }

    public static void exeCommandLine(String outLogPath,List<CommandLine> commandLineList){
        try {
            DefaultExecutor executor = new DefaultExecutor();
            PumpStreamHandler logOut;
            if(outLogPath == null){
                logOut = new PumpStreamHandler(new PrintStream(System.out, true, "GB2312"));
            }else {
                // 重定向stdout和stderr到文件
                FileOutputStream fileOutputStream = new FileOutputStream(outLogPath);
                logOut = new PumpStreamHandler(fileOutputStream);
            }
            executor.setStreamHandler(logOut);
            System.out.println("开始合并视频！！！");
            for (int i = 0; i < commandLineList.size(); i++) {
                CommandLine commandLine = commandLineList.get(i);
                executor.execute(commandLine);
            }
            System.out.println("合并完成！");
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    private static final ThreadLocal<StringBuilder> SB_THREADLOCAL = new ThreadLocal<StringBuilder>(){
        @Override
        protected StringBuilder initialValue() {
            return new StringBuilder();
        }
    };

    public static String removeUnChinese(String str){
        if( StringUtils.isBlank(str) ){
            return "";
        }
        StringBuilder sb = SB_THREADLOCAL.get();
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if(StringUtils.isChinese(chars[i])){
                sb.append(chars[i]);
            }
        }
        str = sb.toString();
        sb.setLength(0);
        return str;
    }

    // 加入转义符号
    public static String getEscapeSymbol(String str){
        return "'" + str + "'";
    }

    public static JSONObject getTitleByEntryJson(String jsonPath) {
        return getTitleByEntryJson(new File(jsonPath));
    }

    public static JSONObject getTitleByEntryJson(File jsonFile) {
        JSONObject jsonObject = null;
        if (jsonFile != null && jsonFile.exists() ) {
            // 使用 FileReader 和 Scanner 读取文件内容。
            try (FileReader reader = new FileReader(jsonFile);
                 Scanner scanner = new Scanner(reader)) {
                // scanner.useDelimiter("\\A").next() 读取整个文件内容为一个字符串。
                String jsonString = scanner.useDelimiter("\\A").next();
                // 使用 JsonParser 解析 JSON 字符串，并转换为 JsonObject。
                jsonObject = JSONObject.parseObject(jsonString);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("entry.json not found in directory");
        }
        return jsonObject;
    }

}
